package com.feng.utils
{
	import com.feng.data.UpgradeType;
	import com.feng.model.Player;

	/**
	 * 单挑计算
	 * @author 风之守望者
	 * 2013-3-29
	 */
	public class ChallengeCompute
	{
		/** 普通计算最大深度 */
		public static const GENERAL_MAX_DEPTH:int = 100;

		/** 单挑计算最大深度 */
		public static const CHALLENGE_MAX_DEPTH:int = 100;

		/** 最大深度 */
		public static var maxDepth:int = 100;

		/**
		 *  当前达到的最大深度
		 */
		public static var currentMaxDepth:int = 0;

		/**
		 * 玩家a与玩家b单挑(为了正确性，请在回合开始环境调用)
		 * @param a
		 * @param b
		 * @return 单挑结束后 a的血量减去b的血量(整数表示a赢了，负数表示b赢了，0表示平局)
		 */
		public static function challenge(a:Player, b:Player, depth:int = 0):Number
		{
			depth++;

			if (currentMaxDepth < depth)
				currentMaxDepth = depth;
			/**************** 一个回合开始 *****************/
			a = a.copy();
			b = b.copy();

			//a、bPK一回合（将改变a、b的值）
			pKbout(a, b);

			//如果有一方血量低于0 判处胜负
			if (a.hp <= 0 || b.hp <= 0)
			{
				/**************** 单挑结束 *****************/
				return a.hp - b.hp;
			}
			/**************** 一个回合结束 *****************/

			//如果超出最大深度，立即返回结果
			if (depth >= maxDepth)
			{
				//快速计算结果
				var fastChallengeValue:Number = fastChallenge(a, b);
				return fastChallengeValue;
			}

			//计算 a、b最优属性升级
			var aUp:Player = bestUpgradeType(a, b, depth);
			var bUp:Player = bestUpgradeType(b, a, depth);

			return challenge(aUp, bUp, depth);
		}

		/**
		 * a、bPK一回合（将改变a、b的值）
		 * @param a
		 * @param b
		 *
		 */
		public static function pKbout(a:Player, b:Player):void
		{
			//速度快的玩家
			var fastPlayer:Player = a.speed > b.speed ? a : b;
			//速度慢的玩家
			var slowPlayer:Player = a.speed > b.speed ? b : a;

			//如果俩玩家速度相同
			if (fastPlayer.speed == slowPlayer.speed)
			{
				//互相打两次
				slowPlayer.hp -= fastPlayer.attackDamage(slowPlayer);
				fastPlayer.hp -= slowPlayer.attackDamage(fastPlayer);
				//死了是没法攻击的
				if (slowPlayer.hp > 0 && fastPlayer.hp > 0)
				{
					slowPlayer.hp -= fastPlayer.attackDamage(slowPlayer);
					fastPlayer.hp -= slowPlayer.attackDamage(fastPlayer);
				}
			}
			else
			{
				//速度快的攻击两次
				slowPlayer.hp -= fastPlayer.attackDamage(slowPlayer) * 2;
				//死了是没法攻击的
				if (slowPlayer.hp > 0 && fastPlayer.hp > 0)
				{
					fastPlayer.hp -= slowPlayer.attackDamage(fastPlayer);
				}
			}
		}

		/**
		 * 选择一个对a最有优势的升级属性 (怎么样的才是最好的啊？)
		 * @param a
		 * @param b
		 * @return 对a最有升级属性
		 */
		public static function getBestUpgradeType(a:Player, b:Player, depth:int = 0):int
		{
			a = a.copy();
			b = b.copy();

			//最优升级属性
			var bestUpgradeTypeA:int = UpgradeType.ADD_ATTACK;
			var bestUpgradeTypeB:int = UpgradeType.ADD_ATTACK;

			var i:int = 0;
			var length:int = UpgradeType.upgradeTypeList.length;
			var aUp:Player;
			var bUp:Player;

			//a升级属性后 与 b 的单挑值
			var challengeValue:int;
			var maxValue:int;

			//猜测 b 怎么升
			maxValue = (a.hp + b.hp) * -1;
			for (i = 0; i < length; i++)
			{
				bUp = b.upgrade(UpgradeType.upgradeTypeList[i]);
				challengeValue = fastChallenge(bUp, a);
				
				//寻找最优升级属性
				if (maxValue < challengeValue)
				{
					maxValue = challengeValue;
					bestUpgradeTypeB = UpgradeType.upgradeTypeList[i];
				}
			}
			bUp = b.upgrade(bestUpgradeTypeB);
			
			//尝试升级每种属性
			maxValue = (a.hp + b.hp) * -1;
			for (i = 0; i < length; i++)
			{
				/** ！！！！！ */
				//需要非常注意的地方，只有a升级了，b却没动，不靠谱判断?
				aUp = a.upgrade(UpgradeType.upgradeTypeList[i]);

				challengeValue = fastChallenge(aUp, bUp);
				
				//寻找最优升级属性
				if (maxValue < challengeValue)
				{
					maxValue = challengeValue;
					bestUpgradeTypeA = UpgradeType.upgradeTypeList[i];
				}
			}

			return bestUpgradeTypeA;
		}

		/**
		 * 给a执行最优属性升级
		 * @param a
		 * @param b
		 * @return 升级后的a
		 *
		 */
		public static function bestUpgradeType(a:Player, b:Player, depth:int):Player
		{
			a = a.copy();
			b = b.copy();

			var aUp:Player;
			//计算 a最优升级属性
			var aBestUpgradeType:int = getBestUpgradeType(a, b, depth);
			//a升级属性
			aUp = a.upgrade(aBestUpgradeType);
			return aUp;
		}

		/**
		 * 快速计算 玩家a与玩家b单挑结果 (为了正确性，请在回合开始环境调用)
		 * @param a
		 * @param b
		 * @return 单挑结束后 a的血量减去b的血量(整数表示a赢了，负数表示b赢了，0表示平局)
		 */
		public static function fastChallenge(a:Player, b:Player):Number
		{
			a = a.copy();
			b = b.copy();

			while (a.hp > 0 && b.hp > 0)
			{
				pKbout(a, b);
			}
			return a.hp - b.hp;
		}
	}
}
